package indi.h.security.encryption.asym;

import java.util.HashMap;
import java.util.Map;

import indi.h.security.Parameters;
import indi.h.security.encryption.AbstractCrypt;
import indi.h.security.encryption.sym.SymCryptParameter;
import indi.h.security.encryption.sym.SymFactoryConfig;

public class AsymFactoryConfig<T extends Enum<?>> extends SymFactoryConfig<Enum<?>> {

	private static Map<Enum<?>, String> defaultKEyAgr;
	private static Map<Enum<?>, Enum<?>> defaultKEyAgrMode;
	private static Map<Enum<?>, String> defaultKEyAgrFcatory;

	static {
		defaultKEyAgr = new HashMap<Enum<?>, String>();
		defaultKEyAgrFcatory = new HashMap<Enum<?>, String>();
		defaultKEyAgrMode = new HashMap<Enum<?>, Enum<?>>();

		/**
		 * 
		 */
		defaultLength.put(AsymCryptType.RSA, 1024);

		defaultLength.put(KeyAgrCryptType.DH, 1024);
		defaultLength.put(KeyAgrCryptType.EC, 192);
		defaultLength.put(KeyAgrCryptType.ECMQV, 192);
		defaultLength.put(KeyAgrCryptType.ECDSA, 192);
		defaultLength.put(KeyAgrCryptType.ECDH, 192);
		defaultLength.put(KeyAgrCryptType.ECDHC, 192);
		defaultLength.put(KeyAgrCryptType.ECIES, 192);
		defaultLength.put(KeyAgrCryptType.ECDHWITHSHA1KDF, 192);

		defaultLength.put(IESCryptType.EC, 192);
		/**
		 * 
		 */
		defaultCipher.put(AsymCryptType.RSA, "RSA");
		defaultCipher.put(IESCryptType.EC, "ECIES");

		/**
		 * 
		 */
		defaultKEyAgr.put(KeyAgrCryptType.DH, "DH");
		defaultCipher.put(KeyAgrCryptType.DH, "DES");
		defaultKEyAgrMode.put(KeyAgrCryptType.DH, KeyAgrMode.BASE);
		defaultKEyAgrFcatory.put(KeyAgrCryptType.DH, "DH");

		defaultKEyAgr.put(KeyAgrCryptType.EC, "ECCDH");
		defaultCipher.put(KeyAgrCryptType.EC, "DES");
		defaultKEyAgrMode.put(KeyAgrCryptType.EC, KeyAgrMode.MQV);
		defaultKEyAgrFcatory.put(KeyAgrCryptType.EC, "EC");

		defaultKEyAgr.put(KeyAgrCryptType.ECMQV, "ECMQV");
		defaultCipher.put(KeyAgrCryptType.ECMQV, "DES");
		defaultKEyAgrMode.put(KeyAgrCryptType.ECMQV, KeyAgrMode.MQV);
		defaultKEyAgrFcatory.put(KeyAgrCryptType.ECMQV, "ECMQV");

		defaultKEyAgr.put(KeyAgrCryptType.ECDSA, "ECCDH");
		defaultCipher.put(KeyAgrCryptType.ECDSA, "DES");
		defaultKEyAgrMode.put(KeyAgrCryptType.ECDSA, KeyAgrMode.MQV);
		defaultKEyAgrFcatory.put(KeyAgrCryptType.ECDSA, "ECCDH");

		defaultKEyAgr.put(KeyAgrCryptType.ECDH, "ECDH");
		defaultCipher.put(KeyAgrCryptType.ECDH, "DES");
		defaultKEyAgrMode.put(KeyAgrCryptType.ECDH, KeyAgrMode.MQV);
		defaultKEyAgrFcatory.put(KeyAgrCryptType.ECDH, "ECDH");

		defaultKEyAgr.put(KeyAgrCryptType.ECDHC, "ECDHC");
		defaultCipher.put(KeyAgrCryptType.ECDHC, "DES");
		defaultKEyAgrMode.put(KeyAgrCryptType.ECDHC, KeyAgrMode.MQV);
		defaultKEyAgrFcatory.put(KeyAgrCryptType.ECDHC, "ECDHC");

		defaultKEyAgr.put(KeyAgrCryptType.ECIES, "ECDHC");
		defaultCipher.put(KeyAgrCryptType.ECIES, "DES");
		defaultKEyAgrMode.put(KeyAgrCryptType.ECIES, KeyAgrMode.MQV);
		defaultKEyAgrFcatory.put(KeyAgrCryptType.ECIES, "EC");

		defaultKEyAgr.put(KeyAgrCryptType.ECDHWITHSHA1KDF, "ECDHWITHSHA1KDF");
		defaultCipher.put(KeyAgrCryptType.ECDHWITHSHA1KDF, "DES");
		defaultKEyAgrMode.put(KeyAgrCryptType.ECDHWITHSHA1KDF, KeyAgrMode.MQV);
		defaultKEyAgrFcatory.put(KeyAgrCryptType.ECDHWITHSHA1KDF, "EC");
	}

	@Override
	public Parameters getParameters() {
		// TODO Auto-generated method stub
		if (e instanceof IESCryptType) {
			SymCryptParameter ecp = initDefaultParam(new IESCryptParameter());
			return ecp;
		} else if (e instanceof AsymCryptType) {
			SymCryptParameter dp = initDefaultParam(new AsymCryptParameter());
			return dp;
		} else if (e instanceof KeyAgrCryptType) {
			KeyAgrCryptParameter dp = (KeyAgrCryptParameter) initDefaultParam(new KeyAgrCryptParameter());
			dp.setKeyAgrAlgorithm(defaultKEyAgr.get(e));
			dp.setKeyAgrMode(defaultKEyAgrMode.get(e));
			dp.setKeyFactory(defaultKEyAgrFcatory.get(e));
			return dp;
		}
		return super.getParameters();
	}

	@Override
	protected SymCryptParameter initDefaultParam(SymCryptParameter s) {
		// TODO Auto-generated method stub
		super.initDefaultParam(s);
		AsymCryptParameter acp = (AsymCryptParameter) s;
		acp.setKeyFactory(e.toString());
		acp.setCipherAlgorithm(defaultCipher.get(e));
		return acp;
	}

	@Override
	public AbstractCrypt newCrypt() {
		// TODO Auto-generated method stub
		if (e instanceof IESCryptType)
			return new IESCryptImp();
		if (e instanceof KeyAgrCryptType)
			return new KeyAgrCryptImp();
		if (e instanceof AsymCryptType)
			return new AsymCryptImp();
		return null;
	}

}
